"""
通知数据模型
@deprecated: 此模型已废弃，请使用 NotifyLog 模型替代
"""

from sqlalchemy import Column, Integer, String, DateTime, Boolean, ForeignKey, Text, Enum
from sqlalchemy.dialects.mysql import JSON
from sqlalchemy.sql import func
from sqlalchemy.orm import relationship
import enum

from app.database import Base


class NotificationType(enum.Enum):
    """通知类型枚举"""
    PRODUCT_FOUND = "product_found"      # 发现新商品
    MONITOR_STARTED = "monitor_started"  # 监控开始
    MONITOR_EXPIRED = "monitor_expired"  # 监控过期
    BALANCE_LOW = "balance_low"          # 余额不足
    SYSTEM_MESSAGE = "system_message"   # 系统消息


class NotificationChannel(enum.Enum):
    """通知渠道枚举"""
    EMAIL = "email"          # 邮件
    WECHAT = "wechat"        # 微信公众号
    WEBSOCKET = "websocket"  # WebSocket推送
    SMS = "sms"              # 短信


class NotificationStatus(enum.Enum):
    """通知状态枚举"""
    PENDING = "pending"      # 待发送
    SENT = "sent"            # 已发送
    DELIVERED = "delivered"  # 已送达
    FAILED = "failed"        # 发送失败
    READ = "read"            # 已读


class Notification(Base):
    """通知记录表"""
    __tablename__ = "notifications"

    # 基础字段
    id = Column(Integer, primary_key=True, index=True, comment="通知ID")
    user_id = Column(Integer, ForeignKey("users.id"), nullable=False, comment="用户ID")
    monitor_id = Column(Integer, ForeignKey("monitors.id"), nullable=True, comment="关联监控任务ID")
    
    # 通知内容
    notification_type = Column(Enum(NotificationType), nullable=False, comment="通知类型")
    title = Column(String(200), nullable=False, comment="通知标题")
    content = Column(Text, nullable=False, comment="通知内容")
    
    # 通知渠道和状态
    channel = Column(Enum(NotificationChannel), nullable=False, comment="通知渠道")
    status = Column(Enum(NotificationStatus), default=NotificationStatus.PENDING, comment="通知状态")
    
    # 扩展数据（JSON格式）
    data = Column(JSON, nullable=True, comment="扩展数据")
    # 示例：
    # 商品通知: {"product_id": 123, "product_title": "商品名", "product_url": "链接"}
    # 监控通知: {"monitor_name": "监控名", "keyword": "关键词"}
    
    # 发送信息
    recipient = Column(String(255), nullable=False, comment="接收者（邮箱/微信openid等）")
    sender = Column(String(255), nullable=True, comment="发送者")
    
    # 发送结果
    sent_at = Column(DateTime(timezone=True), nullable=True, comment="发送时间")
    delivered_at = Column(DateTime(timezone=True), nullable=True, comment="送达时间")
    read_at = Column(DateTime(timezone=True), nullable=True, comment="阅读时间")
    
    # 错误信息
    error_message = Column(Text, nullable=True, comment="错误信息")
    retry_count = Column(Integer, default=0, comment="重试次数")
    max_retries = Column(Integer, default=3, comment="最大重试次数")
    
    # 优先级和过期
    priority = Column(Integer, default=5, comment="优先级（1-10，数字越小优先级越高）")
    expires_at = Column(DateTime(timezone=True), nullable=True, comment="过期时间")
    
    # 时间字段
    created_at = Column(DateTime(timezone=True), server_default=func.now(), comment="创建时间")
    updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), comment="更新时间")
    
    # 关联关系
    user = relationship("User", back_populates="notifications")
    monitor = relationship("Monitor", back_populates="notifications")
    product_notification = relationship("ProductNotification", back_populates="notification", uselist=False)

    def __repr__(self):
        return f"<Notification(id={self.id}, user_id={self.user_id}, type={self.notification_type.value}, status={self.status.value})>"

    @property
    def is_expired(self):
        """检查是否已过期"""
        if not self.expires_at:
            return False
        return func.now() > self.expires_at

    @property
    def can_retry(self):
        """检查是否可以重试"""
        return self.retry_count < self.max_retries and self.status == NotificationStatus.FAILED

    def mark_as_sent(self):
        """标记为已发送"""
        self.status = NotificationStatus.SENT
        self.sent_at = func.now()

    def mark_as_delivered(self):
        """标记为已送达"""
        self.status = NotificationStatus.DELIVERED
        self.delivered_at = func.now()

    def mark_as_failed(self, error_message=None):
        """标记为发送失败"""
        self.status = NotificationStatus.FAILED
        self.error_message = error_message
        self.retry_count += 1

    def mark_as_read(self):
        """标记为已读"""
        self.status = NotificationStatus.READ
        self.read_at = func.now()

    @classmethod
    def create_product_notification(cls, user_id, monitor_id, product_data, channel=NotificationChannel.EMAIL):
        """创建商品发现通知"""
        title = f"发现新商品: {product_data.get('title', '未知商品')}"
        content = f"""
发现符合您监控条件的新商品：

商品名称：{product_data.get('title', '未知')}
商品价格：{product_data.get('price', '未知')} {product_data.get('currency', 'CNY')}
卖家：{product_data.get('seller_name', '未知')}
发布时间：{product_data.get('published_at', '未知')}
商品链接：{product_data.get('product_url', '无')}

请及时查看，祝您购物愉快！
        """.strip()
        
        return cls(
            user_id=user_id,
            monitor_id=monitor_id,
            notification_type=NotificationType.PRODUCT_FOUND,
            title=title,
            content=content,
            channel=channel,
            data=product_data,
            priority=2  # 商品通知优先级较高
        )

    @classmethod
    def create_monitor_expired_notification(cls, user_id, monitor_id, monitor_name, channel=NotificationChannel.EMAIL):
        """创建监控过期通知"""
        title = f"监控任务已过期: {monitor_name}"
        content = f"""
您的监控任务"{monitor_name}"已到期。

如需继续监控，请重新创建监控任务。
感谢您的使用！
        """.strip()
        
        return cls(
            user_id=user_id,
            monitor_id=monitor_id,
            notification_type=NotificationType.MONITOR_EXPIRED,
            title=title,
            content=content,
            channel=channel,
            data={"monitor_name": monitor_name},
            priority=5
        )
